package com.koi.satoken.config;

import cn.dev33.satoken.stp.StpInterface;
import cn.hutool.core.collection.CollectionUtil;
import com.koi.common.ex.koi.YUtil;
import com.koi.common.satoken.KoiLoginUtil;
import com.koi.satoken.service.menu.SaMenuService;
import com.koi.satoken.service.role.SaRoleService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @author ･ᴗ･
 * @description [StpInterfaceImpl自定义权限验证接口扩展]
 */
@Slf4j
@RequiredArgsConstructor
@Component // 保证此类被SpringBoot扫描，完成Sa-Token的自定义权限验证扩展
public class KoiSaTokenStpInterfaceImpl implements StpInterface {

    private final SaRoleService saRoleService;

    private final SaMenuService saMenuService;

    /**
     * @description [返回一个账号所拥有的角色标识集合 (权限与角色可分开校验)]
     * @author ･ᴗ･
     */
    @Override
    public List<String> getRoleList(Object loginId, String loginType) {
        // 1、数据库查询用户拥有的角色码
        List<String> roleCodeList = saRoleService.listAuthRoleCode(Long.valueOf(loginId.toString()));
        // 2、返回角色码集合
        return roleCodeList;
    }

    /**
     * @description [返回一个账号所拥有的权限码集合]
     * @author ･ᴗ･
     */
    @Override
    public List<String> getPermissionList(Object loginId, String loginType) {
        // 1、声明权限码集合
        Set<String> permissionSet = new HashSet<>();
        // 2、遍历角色列表，查询拥有的角色权限码
        List<String> roleKeyList = getRoleList(loginId, loginType);
        if (CollectionUtil.isEmpty(roleKeyList)) {
            return new ArrayList<>(permissionSet);
        }
        // 3、角色判断：超级管理员 roleKeyList.contains(KoiConstants.KOI_ADMIN)
        if (KoiLoginUtil.getIsKoiAdmin()) {
            permissionSet.add("*");
            return new ArrayList<>(permissionSet);
        }
        // 4、角色判断：其他角色
        List<String> menuAuthlist = null;
        for (String roleKey : roleKeyList) {
            // 5、根据角色码查询拥有的权限码
            menuAuthlist = saMenuService.listMenuAuth(roleKey);
            YUtil.isTrue(CollectionUtil.isEmpty(menuAuthlist), "该用户角色未分配菜单权限，禁止登录");
            permissionSet.addAll(menuAuthlist);
        }
        // 6、返回权限码集合
        return new ArrayList<>(permissionSet);
    }

}
